package com.asiainfo.integration.actions;

import com.asiainfo.integration.utils.tibjmsUtilities;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Usage:
 *
 * @author Charkey
 * @date 2015/11/19
 */
@WebServlet(urlPatterns = "/message/receive", asyncSupported = true)
public class ReceiveMsgAction extends HttpServlet {

    Connection connection = null;

    Session session = null;

    String text = null;

    MessageConsumer msgConsumer = null;

    Destination destination = null;

    public static final Logger INFO_LOG = Logger.getLogger(ReceiveMsgAction.class);

    private static final String INITIAL_CONTEXT_FACTORY = "com.tibco.tibjms.naming.TibjmsInitialContextFactory";

    private static final int BYTES_DOWNLOAD = 1024;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Map<String, String> propertiesMap = new HashMap<String, String>();

        String connection_url = request.getParameter("connection_url").trim();
        String connection_factory = request.getParameter("connection_factory").trim();
        String username = request.getParameter("username").trim();
        String password = request.getParameter("password").trim();
        String queue_name = request.getParameter("queue_name").trim();
        String message_content = request.getParameter("message_content");

        String interfaceName = request.getParameter("interface_name");
        String save_to_file = request.getParameter("save_to_file");

        request.setAttribute("connection_url", connection_url);
        request.setAttribute("connection_factory", connection_factory);
        request.setAttribute("username", username);
        request.setAttribute("password", password);
        request.setAttribute("queue_name", queue_name);
        request.setAttribute("message_content", message_content);
        request.setAttribute("interface_name", interfaceName);

        try {
            Hashtable<String, String> environment = new Hashtable<String, String>();
            environment.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
            environment.put(Context.PROVIDER_URL, connection_url);
            environment.put(Context.SECURITY_PRINCIPAL, username);
            environment.put(Context.SECURITY_CREDENTIALS, password);
            InitialContext ctx = new InitialContext(environment);
            ConnectionFactory factory = (ConnectionFactory) ctx.lookup(connection_factory);

            /* create the connection */
            connection = factory.createConnection(username, password);

            /* create the session */
            session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

            /* create the destination */
            /*
             * if(useTopic) destination = session.createTopic(name); else
             */
            destination = session.createQueue(queue_name);

             /* start the connection */
            connection.start();

            /* create the consumer */
            msgConsumer = session.createConsumer(destination);

            TextMessage textMsg = (TextMessage) msgConsumer.receiveNoWait();

            session.close();
            connection.stop();

            if (textMsg != null) {

                text = textMsg.getText();

                Enumeration pros = textMsg.getPropertyNames();
                do {
                    String propsName = pros.nextElement().toString();
                    propertiesMap.put(propsName, textMsg.getObjectProperty(propsName).toString());
                } while (pros.hasMoreElements());
                propertiesMap.put("JMSMessageID", textMsg.getJMSMessageID());
                propertiesMap.put("JMSTimestamp", textMsg.getJMSTimestamp()+"");
                propertiesMap.put("JMSCorrelationID", textMsg.getJMSCorrelationID());
                propertiesMap.put("JMSReplyTo", textMsg.getJMSReplyTo() != null ? textMsg.getJMSReplyTo().toString() : null);
                propertiesMap.put("JMSDestination", textMsg.getJMSDestination().toString());
                propertiesMap.put("JMSDeliveryMode", textMsg.getJMSDeliveryMode()+"");
                propertiesMap.put("JMSRedelivered", textMsg.getJMSRedelivered()+"");
                propertiesMap.put("JMSType", textMsg.getJMSType());
                propertiesMap.put("JMSExpiration", textMsg.getJMSExpiration()+"");
                propertiesMap.put("JMSPriority", textMsg.getJMSPriority()+"");
                request.setAttribute("propertiesMap", propertiesMap);

                if (save_to_file !=null && save_to_file.equals("on")) {
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
                    String fileName = interfaceName + "-" + formatter.format(new Date()) + ".txt";
                    response.setContentType("text/plain");
                    response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                    InputStream inputStream = new ByteArrayInputStream(text.getBytes());
                    int read;
                    byte[] bytes = new byte[BYTES_DOWNLOAD];
                    OutputStream os = response.getOutputStream();
                    while ((read = inputStream.read(bytes)) != -1) {
                        os.write(bytes, 0, read);
                    }
                    os.flush();
                    os.close();
                } else {
                    request.setAttribute("is_error", false);
                    request.setAttribute("message_content", text);
                    request.getRequestDispatcher("/WEB-INF/pages/receive.jsp").forward(request, response);
                }
            } else {
                request.setAttribute("is_error", true);
                request.setAttribute("message_content", "");
                request.setAttribute("error_message", "No Message in queue!");
                request.getRequestDispatcher("/WEB-INF/pages/receive.jsp").forward(request, response);
            }
        } catch (JMSSecurityException e) {
            e.printStackTrace();
            request.setAttribute("error_message", e.getMessage());
            request.setAttribute("is_error", true);
            request.getRequestDispatcher("/WEB-INF/pages/receive.jsp").forward(request, response);
        } catch (JMSException e) {
            e.printStackTrace();
            request.setAttribute("error_message", e.getMessage());
            request.setAttribute("is_error", true);
            request.getRequestDispatcher("/WEB-INF/pages/receive.jsp").forward(request, response);
        } catch (NamingException e) {
            e.printStackTrace();
            request.setAttribute("error_message", e.getMessage());
            request.setAttribute("is_error", true);
            request.getRequestDispatcher("/WEB-INF/pages/receive.jsp").forward(request, response);
        }

    }

}